﻿using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
 
using System.Collections.Concurrent;



namespace AISservice.Common
{
    public class SafeMiddleware
    {

        private readonly RequestDelegate _next;
        private readonly int _maxRequests;  
        private readonly ConcurrentDictionary<string, RateLimiter> _rateLimiters;

        public SafeMiddleware(RequestDelegate next, int maxRequests)
        {
            _next = next;
            _maxRequests = maxRequests;
            _rateLimiters = new ConcurrentDictionary<string, RateLimiter>();
        }

        public async Task InvokeAsync(HttpContext context)
        {
            // 获取客户端的唯一标识（例如 IP 地址）
            var clientId = context.Connection.RemoteIpAddress.ToString();

            var rateLimiter = _rateLimiters.GetOrAdd(clientId, _ => new RateLimiter(_maxRequests));

            if (rateLimiter.AllowRequest())
            {
                await _next(context);
            }
            else
            {
                context.Response.StatusCode = StatusCodes.Status429TooManyRequests;
                await context.Response.WriteAsync("网路异常。请稍后再试.");
            }
        }


    }


    public class RateLimiter
    {
        private readonly int _maxRequests;
        private int _requestCount;
        private DateTime _windowStart;

        public RateLimiter(int maxRequests)
        {
            _maxRequests = maxRequests;
            _requestCount = 0;
            _windowStart = DateTime.UtcNow;
        }

        public bool AllowRequest()
        {
            var now = DateTime.UtcNow;

            if ((now - _windowStart).TotalSeconds > 60)
            {
                _requestCount = 0;
                _windowStart = now;
            }

            
            if (_requestCount < _maxRequests)
            {
                _requestCount++;
                return true;
            }

            return false;
        }
    }
}
